import { isStr, isFn, Placement, Update, updateNode } from "./utils"
import { updateHostComponent, updateFnComponent } from './ReactFiberReconcile'

let wipRoot = null
let nextUnitOfWork = null

// 回调入口
function workLoop(IdleDeadline) {
    // console.log('~~workLoop') //! 这里只被浏览器回调一次？
    //! 发现浏览器给所有的fiber更新都预留好了时间，保证所有fiber处理完正好?
    while (nextUnitOfWork && IdleDeadline.timeRemaining() > 0) {
        // 处理当前任务，返回下一个任务
        // console.log('~~timeRemaining()', IdleDeadline.timeRemaining(), nextUnitOfWork)
        nextUnitOfWork = perFormUnitOfWork(nextUnitOfWork)
    }
    // 如果fiber处理完，这里会被不断的调用，如果打印就会非常耗性能
    // console.log('~~——————————————workLoop')
    requestIdleCallback(workLoop)
    if (!nextUnitOfWork && wipRoot) {
        commitRoot()
    }
    
}

function commitRoot() {
    isFn(wipRoot.type) ? commitWork(wipRoot) : commitWork(wipRoot.child)
    console.log('~~commitRoot',isFn(wipRoot.type),wipRoot)
    wipRoot = null
}

function commitWork(wip) {
    if (!wip) return
    //更新自己
    const { stateNode, flags } = wip
    // const parentNode = wip.return.stateNode
    let parentNode = getParentNode(wip.return)
    console.log('~~commitWork wip', wip)
    console.log('~~parentNode', parentNode)
    // console.log('~~flag & Placement && stateNode', flags,Placement,stateNode)
    if (flags & Placement && stateNode) { // 插入节点
        // console.log('~~parentNode', parentNode, stateNode)
        parentNode.appendChild(stateNode)
    }
    if (flags & Update && stateNode) {
        updateNode(stateNode, wip.alterNate.props, wip.props)

    }
    // 更新child
    commitWork(wip.child)
    // 更新兄弟
    commitWork(wip.sibling)

}

function getParentNode(wip) {
    let tem = wip
    while (tem) {
        if (tem.stateNode) {
            return tem.stateNode
        }
        tem = tem.return
    }
}
export function scheduleUpdateOnFiber(fiber) {
    fiber.alterNate = { ...fiber }
    wipRoot = fiber
    wipRoot.sibling = null 
    nextUnitOfWork = wipRoot
}

// wip = work in progress，fiber类型
function perFormUnitOfWork(wip) {

    // 更新当前任务
    const { type } = wip

    // 原生标签
    if (isStr(type)) {
        updateHostComponent(wip)
        // 函数组件
    } else if (isFn(type)) {
        updateFnComponent(wip)
    }

    // 返回下一个子节点——王朝的故事
    if (wip.child) {
        return wip.child
    }

    let next = wip
    while (next) {
        if (next.sibling) {
            return next.sibling
        }
        next = next.return
    }

    return null

}


requestIdleCallback(workLoop)